JavaScriptã®AbortControllerã䜿çšããŠãfetchãªã¯ãšã¹ããã¿ã€ããŒãªã©ã®éåææäœã广çã«ãã£ã³ã»ã«ããæ¹æ³ãåŠã³ãããã¯ãªãŒã³ã§é«æ§èœãªã³ãŒãã確ä¿ããŸãã
JavaScript AbortController: éåææäœã®ãã£ã³ã»ã«ããã¹ã¿ãŒãã
çŸä»£ã®Webéçºã§ã¯ãéåææäœã¯è³ãæã«ååšããŸããAPIããã®ããŒã¿ã®ååŸãã¿ã€ããŒã®èšå®ããŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã®åŠçã¯ãç¬ç«ããŠå®è¡ãããæœåšçã«é·æéã«ããã£ãŠå®è¡ãããã³ãŒãã䌎ãããšããããããŸãããã ãããããã®æäœãå®äºããåã«ãã£ã³ã»ã«ããå¿
èŠãããã·ããªãªããããŸããããã§ãJavaScriptã®AbortController
ã€ã³ã¿ãŒãã§ãŒã¹ãç»å ŽããŸããããã¯ãDOMæäœããã®ä»ã®éåæã¿ã¹ã¯ã«ãã£ã³ã»ã«ãªã¯ãšã¹ããéç¥ããããã®ã¯ãªãŒã³ã§å¹ççãªæ¹æ³ãæäŸããŸãã
ãã£ã³ã»ã«ãå¿ èŠãªçç±ãçè§£ãã
æè¡çãªè©³çްã«å ¥ãåã«ãéåææäœããã£ã³ã»ã«ããããšããªãéèŠãªã®ããçè§£ããŸããããæ¬¡ã®äžè¬çãªã·ããªãªãèããŠã¿ãŠãã ããã
- ãŠãŒã¶ãŒããã²ãŒã·ã§ã³: ãŠãŒã¶ãŒãæ€çŽ¢ã¯ãšãªãéå§ããAPIãªã¯ãšã¹ããããªã¬ãŒããŸãããªã¯ãšã¹ããå®äºããåã«å¥ã®ããŒãžã«ãã°ããç§»åããå Žåãå ã®ãªã¯ãšã¹ãã¯ç¡é¢ä¿ã«ãªããäžèŠãªãããã¯ãŒã¯ãã©ãã£ãã¯ãæœåšçãªå¯äœçšãåé¿ããããã«ãã£ã³ã»ã«ããå¿ èŠããããŸãã
- ã¿ã€ã ã¢ãŠã管ç: éåææäœã«ã¿ã€ã ã¢ãŠããèšå®ããŸããã¿ã€ã ã¢ãŠããåããåã«æäœãå®äºããå Žåã¯ãåé·ãªã³ãŒãã®å®è¡ãé²ãããã«ã¿ã€ã ã¢ãŠãããã£ã³ã»ã«ããå¿ èŠããããŸãã
- ã³ã³ããŒãã³ãã®ã¢ã³ããŠã³ã: ReactãVue.jsãªã©ã®ããã³ããšã³ããã¬ãŒã ã¯ãŒã¯ã§ã¯ãã³ã³ããŒãã³ããéåæãªã¯ãšã¹ããè¡ãããšããããããŸããã³ã³ããŒãã³ããã¢ã³ããŠã³ãããããšããã®ã³ã³ããŒãã³ãã«é¢é£ä»ããããŠããé²è¡äžã®ãªã¯ãšã¹ãã¯ãã¡ã¢ãªãªãŒã¯ãã¢ã³ããŠã³ããããã³ã³ããŒãã³ãã®æŽæ°ã«ãã£ãŠçºçãããšã©ãŒãåé¿ããããã«ãã£ã³ã»ã«ããå¿ èŠããããŸãã
- ãªãœãŒã¹å¶çŽ: ãªãœãŒã¹ãå¶çŽãããç°å¢ïŒã¢ãã€ã«ããã€ã¹ãçµã¿èŸŒã¿ã·ã¹ãã ãªã©ïŒã§ã¯ãäžèŠãªæäœããã£ã³ã»ã«ãããšã貎éãªãªãœãŒã¹ãè§£æŸããããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸããããšãã°ããŠãŒã¶ãŒãããŒãžã®ãã®ã»ã¯ã·ã§ã³ãã¹ã¯ããŒã«ããŠéããå Žåã倧ããªç»åã®ããŠã³ããŒãããã£ã³ã»ã«ããŸãã
AbortControllerãšAbortSignalã®ç޹ä»
AbortController
ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãéåææäœã®ãã£ã³ã»ã«ãšããåé¡ã解決ããããã«èšèšãããŠããŸããããã¯ã次ã®2ã€ã®äž»èŠãªã³ã³ããŒãã³ãã§æ§æãããŠããŸãã
- AbortController: ãã®ãªããžã§ã¯ãã¯ããã£ã³ã»ã«ã·ã°ãã«ã管çããŸããããã«ã¯ããã£ã³ã»ã«ãªã¯ãšã¹ããéç¥ããããã«äœ¿çšãããåäžã®ã¡ãœãã
abort()
ããããŸãã - AbortSignal: ãã®ãªããžã§ã¯ãã¯ãæäœãäžæ¢ããå¿
èŠãããã·ã°ãã«ã衚ããŸããããã¯
AbortController
ã«é¢é£ä»ããããŠããããã£ã³ã»ã«å¯èœã«ããå¿ èŠãããéåææäœã«æž¡ãããŸãã
åºæ¬çãªäœ¿çšæ³: Fetchãªã¯ãšã¹ãã®ãã£ã³ã»ã«
fetch
ãªã¯ãšã¹ãããã£ã³ã»ã«ããç°¡åãªäŸããå§ããŸãããã
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/data', { signal })
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
});
// To cancel the fetch request:
controller.abort();
説æ:
AbortController
ã€ã³ã¹ã¿ã³ã¹ãäœæããŸããcontroller
ããé¢é£ä»ããããAbortSignal
ãååŸããŸããsignal
ãfetch
ãªãã·ã§ã³ã«æž¡ããŸãã- ãªã¯ãšã¹ãããã£ã³ã»ã«ããå¿
èŠãããå Žåã¯ã
controller.abort()
ãåŒã³åºããŸãã .catch()
ãããã¯ã§ããšã©ãŒãAbortError
ã§ãããã©ããã確èªããŸããããã§ããå Žåããªã¯ãšã¹ãããã£ã³ã»ã«ãããããšãããããŸãã
AbortErrorã®åŠç
controller.abort()
ãåŒã³åºããããšãfetch
ãªã¯ãšã¹ãã¯AbortError
ã§æåŠãããŸãããã®ãšã©ãŒãã³ãŒãã§é©åã«åŠçããããšãéèŠã§ããããããªããšãæªåŠçã®Promiseãªãžã§ã¯ã·ã§ã³ãäºæããªãåäœã«ã€ãªããå¯èœæ§ããããŸãã
ãšã©ãŒåŠçãå«ããããå ç¢ãªäŸã次ã«ç€ºããŸãã
const controller = new AbortController();
const signal = controller.signal;
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data', { signal });
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log('Data:', data);
return data;
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
return null; // Or throw the error to be handled further up
} else {
console.error('Fetch error:', error);
throw error; // Re-throw the error to be handled further up
}
}
}
fetchData();
// To cancel the fetch request:
controller.abort();
AbortErrorãåŠçããããã®ãã¹ããã©ã¯ãã£ã¹:
- ãšã©ãŒåã確èªãã: åžžã«
error.name === 'AbortError'
ãã©ããã確èªããŠãæ£ãããšã©ãŒã¿ã€ããåŠçããŠããããšã確èªããŸãã - ããã©ã«ãå€ãè¿ãããåã¹ããŒãã: ã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ã«å¿ããŠãããã©ã«ãå€ïŒäŸïŒ
null
ïŒãè¿ãããã³ãŒã«ã¹ã¿ãã¯ãããã«äžã«åŠçããããã«ãšã©ãŒãåã¹ããŒããããšãã§ããŸãã - ãªãœãŒã¹ãã¯ãªãŒã³ã¢ãããã: éåææäœãäœããã®ãªãœãŒã¹ïŒã¿ã€ããŒãã€ãã³ããªã¹ããŒãªã©ïŒãå²ãåœãŠãå Žåã¯ã
AbortError
ãã³ãã©ãŒã§ããããã¯ãªãŒã³ã¢ããããŸãã
AbortSignalã䜿çšããã¿ã€ããŒã®ãã£ã³ã»ã«
AbortSignal
ã¯ãsetTimeout
ãŸãã¯setInterval
ã§äœæãããã¿ã€ããŒããã£ã³ã»ã«ããããã«ã䜿çšã§ããŸããçµã¿èŸŒã¿ã®ã¿ã€ããŒé¢æ°ãAbortSignal
ãçŽæ¥ãµããŒãããŠããªããããããã«ã¯ããå°ãæäœæ¥ãå¿
èŠã§ããã¢ããŒãã·ã°ãã«ããªãã¹ã³ããããªã¬ãŒããããšãã«ã¿ã€ããŒãã¯ãªã¢ããã«ã¹ã¿ã 颿°ãäœæããå¿
èŠããããŸãã
function cancellableTimeout(callback, delay, signal) {
let timeoutId;
const timeoutPromise = new Promise((resolve, reject) => {
timeoutId = setTimeout(() => {
resolve(callback());
}, delay);
signal.addEventListener('abort', () => {
clearTimeout(timeoutId);
reject(new Error('Timeout Aborted'));
});
});
return timeoutPromise;
}
const controller = new AbortController();
const signal = controller.signal;
cancellableTimeout(() => {
console.log('Timeout executed');
}, 2000, signal)
.then(() => console.log("Timeout finished successfully"))
.catch(err => console.log(err));
// To cancel the timeout:
controller.abort();
説æ:
cancellableTimeout
颿°ã¯ãã³ãŒã«ããã¯ãé å»¶ãããã³AbortSignal
ãåŒæ°ãšããŠåããŸããsetTimeout
ãèšå®ããã¿ã€ã ã¢ãŠãIDãä¿åããŸããabort
ã€ãã³ãããªãã¹ã³ããAbortSignal
ã«ã€ãã³ããªã¹ããŒã远å ããŸããabort
ã€ãã³ããããªã¬ãŒããããšãã€ãã³ããªã¹ããŒã¯ã¿ã€ã ã¢ãŠããã¯ãªã¢ãããããã¹ãæåŠããŸãã
ã€ãã³ããªã¹ããŒã®ãã£ã³ã»ã«
ã¿ã€ããŒãšåæ§ã«ãAbortSignal
ã䜿çšããŠã€ãã³ããªã¹ããŒããã£ã³ã»ã«ã§ããŸããããã¯ãã¢ã³ããŠã³ããããŠããã³ã³ããŒãã³ãã«é¢é£ä»ããããŠããã€ãã³ããªã¹ããŒãåé€ããå Žåã«ç¹ã«åœ¹ç«ã¡ãŸãã
const controller = new AbortController();
const signal = controller.signal;
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log('Button clicked!');
}, { signal });
// To cancel the event listener:
controller.abort();
説æ:
signal
ãaddEventListener
ã¡ãœããã®ãªãã·ã§ã³ãšããŠæž¡ããŸããcontroller.abort()
ãåŒã³åºããããšãã€ãã³ããªã¹ããŒã¯èªåçã«åé€ãããŸãã
Reactã³ã³ããŒãã³ãã§ã®AbortController
Reactã§ã¯ãã³ã³ããŒãã³ããã¢ã³ããŠã³ãããããšãã«AbortController
ã䜿çšããŠéåææäœããã£ã³ã»ã«ã§ããŸããããã¯ãã¢ã³ããŠã³ããããã³ã³ããŒãã³ãã®æŽæ°ã«ãã£ãŠçºçããã¡ã¢ãªãªãŒã¯ããšã©ãŒãé²ãããã«äžå¯æ¬ ã§ããuseEffect
ããã¯ã䜿çšããäŸã次ã«ç€ºããŸãã
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data', { signal });
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
setData(data);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
}
}
fetchData();
return () => {
controller.abort(); // Cancel the fetch request when the component unmounts
};
}, []); // Empty dependency array ensures this effect runs only once on mount
return (
{data ? (
Data: {JSON.stringify(data)}
) : (
Loading...
)}
);
}
export default MyComponent;
説æ:
useEffect
ããã¯å ã«AbortController
ãäœæããŸããsignal
ãfetch
ãªã¯ãšã¹ãã«æž¡ããŸããuseEffect
ããã¯ããã¯ãªãŒã³ã¢ãã颿°ãè¿ããŸãããã®é¢æ°ã¯ãã³ã³ããŒãã³ããã¢ã³ããŠã³ãããããšãã«åŒã³åºãããŸãã- ã¯ãªãŒã³ã¢ãã颿°å
ã§ã
controller.abort()
ãåŒã³åºããŠfetchãªã¯ãšã¹ãããã£ã³ã»ã«ããŸãã
é«åºŠãªãŠãŒã¹ã±ãŒã¹
AbortSignalã®ãã§ãŒã³
å Žåã«ãã£ãŠã¯ãè€æ°ã®AbortSignal
ããã§ãŒã³ãããå ŽåããããŸããããšãã°ãåã³ã³ããŒãã³ãã®æäœããã£ã³ã»ã«ããå¿
èŠããã芪ã³ã³ããŒãã³ãããããããããŸãããããã¯ãæ°ããAbortController
ãäœæãããã®ã·ã°ãã«ã芪ã³ã³ããŒãã³ããšåã³ã³ããŒãã³ãã®äž¡æ¹ã«æž¡ãããšã§å®çŸã§ããŸãã
ãµãŒãããŒãã£ã©ã€ãã©ãªã§ã®AbortControllerã®äœ¿çš
AbortSignal
ãçŽæ¥ãµããŒãããŠããªããµãŒãããŒãã£ã©ã€ãã©ãªã䜿çšããŠããå Žåã¯ãã©ã€ãã©ãªã®ãã£ã³ã»ã«ã¡ã«ããºã ãšé£æºããããã«ã³ãŒããé©åãããå¿
èŠãããå ŽåããããŸããããã«ã¯ãAbortSignal
ãåŠçããç¬èªã®é¢æ°ã§ã©ã€ãã©ãªã®éåæé¢æ°ãã©ããããããšãå«ãŸããå ŽåããããŸãã
AbortControllerã䜿çšããå©ç¹
- ããã©ãŒãã³ã¹ã®åäž: äžèŠãªæäœããã£ã³ã»ã«ãããšããããã¯ãŒã¯ãã©ãã£ãã¯ãCPU䜿çšçãããã³ã¡ã¢ãªæ¶è²»ãåæžã§ããç¹ã«ãªãœãŒã¹ãå¶çŽãããããã€ã¹ã§ããã©ãŒãã³ã¹ãåäžããŸãã
- ããã¯ãªãŒã³ãªã³ãŒã:
AbortController
ã¯ããã£ã³ã»ã«ã®ç®¡çã«å¯Ÿããæšæºåããããšã¬ã¬ã³ããªæ¹æ³ãæäŸããã³ãŒããããèªã¿ããããä¿å®ããããããŸãã - ã¡ã¢ãªãªãŒã¯ã®é²æ¢: ã¢ã³ããŠã³ããããã³ã³ããŒãã³ãã«é¢é£ä»ããããŠããéåææäœããã£ã³ã»ã«ãããšãã¡ã¢ãªãªãŒã¯ãã¢ã³ããŠã³ããããã³ã³ããŒãã³ãã®æŽæ°ã«ãã£ãŠçºçãããšã©ãŒãé²ããŸãã
- ããè¯ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹: ç¡é¢ä¿ãªãªã¯ãšã¹ãããã£ã³ã»ã«ãããšãå€ãæ å ±ã®è¡šç€ºãé²ããèªèãããã¬ã€ãã³ã·ãççž®ããããšã§ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžãããããšãã§ããŸãã
ãã©ãŠã¶ã®äºææ§
AbortController
ã¯ãChromeãFirefoxãSafariãEdgeãªã©ã®ææ°ã®ãã©ãŠã¶ã§åºããµããŒããããŠããŸããææ°ã®æ
å ±ã«ã€ããŠã¯ãMDN Web Docsã®äºææ§ããŒãã«ã確èªããŠãã ããã
ããªãã£ã«
AbortController
ããã€ãã£ãã«ãµããŒãããŠããªãå€ããã©ãŠã¶ã®å Žåã¯ãããªãã£ã«ã䜿çšã§ããŸããããªãã£ã«ãšã¯ãå€ããã©ãŠã¶ã§æ°ããæ©èœã®æ©èœãæäŸããã³ãŒãã®ããšã§ãããªã³ã©ã€ã³ã§å©çšã§ããAbortController
ããªãã£ã«ãããã€ããããŸãã
çµè«
AbortController
ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãJavaScriptã§éåææäœã管çããããã®åŒ·åãªããŒã«ã§ããAbortController
ã䜿çšãããšããã£ã³ã»ã«ãé©åã«åŠçãããããã¯ãªãŒã³ã§ããã髿§èœã§ãããå
ç¢ãªã³ãŒããäœæã§ããŸããAPIããã®ããŒã¿ã®ååŸãã¿ã€ããŒã®èšå®ãã€ãã³ããªã¹ããŒã®ç®¡çãªã©ãAbortController
ã¯Webã¢ããªã±ãŒã·ã§ã³å
šäœã®å質ãåäžãããã®ã«åœ¹ç«ã¡ãŸãã